using WeatherSystem.API.Models;
using WeatherSystem.API.Specifications;

namespace WeatherSystem.API.Repositories
{
    /// <summary>
    /// 城市Repository旧接口适配器
    /// 用于向后兼容新的读写分离架构
    /// </summary>
    public class LegacyCityAdapter : ICityRepository
    {
        private readonly IReadRepository<City> _readRepository;
        private readonly IWriteRepository<City> _writeRepository;

        public LegacyCityAdapter(IReadRepository<City> readRepository, IWriteRepository<City> writeRepository)
        {
            _readRepository = readRepository;
            _writeRepository = writeRepository;
        }

        public async Task<City?> GetByNameAsync(string name)
        {
            var spec = new CitySpecification(name);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.FirstOrDefault();
        }

        public async Task<List<City>> GetActiveCitiesAsync()
        {
            var spec = new CitySpecification(null, null, true);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task<PagedResult<object>> GetCitiesPagedAsync(
            int page, int pageSize, bool? isActive = null,
            string? search = null, string? country = null)
        {
            var spec = new CitySpecification(search, country, isActive);
            var result = await _readRepository.GetProjectedPagedAsync(
                c => new { c.Id, c.Name, c.Country, c.IsActive, c.CreatedAt },
                page, pageSize, spec);

            // Convert PagedResult<anonymous type> to PagedResult<object>
            var data = result.Data.Select(d => (object)d).ToList();
            return new PagedResult<object>(data, result.TotalCount, result.Page, result.PageSize);
        }

        public async Task<City?> GetByNameAndCountryAsync(string name, string country)
        {
            var spec = new CitySpecification(name, country);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.FirstOrDefault();
        }

        public async Task<List<City>> GetCitiesByCountryAsync(string country)
        {
            var spec = new CitySpecification(country: country);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task<bool> IsCityExistsAsync(string name, string country)
        {
            var spec = new CitySpecification(name, country);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.Any();
        }

        public async Task<bool> IsCityNameExistsAsync(string name, Guid? excludeId = null)
        {
            var spec = excludeId.HasValue
                ? new CitySpecification(name, excludeId.Value)
                : new CitySpecification(name);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.Any();
        }

        // 实现基础接口方法
        public async Task<City?> GetByIdAsync(Guid id)
        {
            return await _readRepository.GetByIdAsync(id);
        }

        public async Task<IEnumerable<City>> GetAllAsync()
        {
            return await _readRepository.GetAllAsync();
        }

        public async Task<IEnumerable<City>> FindAsync(System.Linq.Expressions.Expression<Func<City, bool>> predicate)
        {
            var spec = new CitySpecification(predicate);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task AddAsync(City entity)
        {
            await _writeRepository.AddAsync(entity);
        }

        public async Task AddRangeAsync(IEnumerable<City> entities)
        {
            await _writeRepository.AddRangeAsync(entities);
        }

        public async Task UpdateAsync(City entity)
        {
            await _writeRepository.UpdateAsync(entity);
        }

        public async Task UpdateRangeAsync(IEnumerable<City> entities)
        {
            await _writeRepository.UpdateRangeAsync(entities);
        }

        public async Task DeleteAsync(City entity)
        {
            await _writeRepository.DeleteAsync(entity);
        }

        public async Task DeleteRangeAsync(IEnumerable<City> entities)
        {
            await _writeRepository.DeleteRangeAsync(entities);
        }

        public async Task<int> CountAsync(System.Linq.Expressions.Expression<Func<City, bool>>? predicate = null)
        {
            var spec = predicate != null ? new CitySpecification(predicate) : null;
            return await _readRepository.CountAsync(spec);
        }

        // 实现IReadRepository接口的新方法
        public async Task<City?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetByIdAsync(id, cancellationToken);
        }

        public async Task<IEnumerable<City>> GetAllAsync(CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetAllAsync(cancellationToken);
        }

        public async Task<IEnumerable<City>> GetBySpecificationAsync(ISpecification<City> specification, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetBySpecificationAsync(specification, cancellationToken);
        }

        public async Task<City?> GetSingleBySpecificationAsync(ISpecification<City> specification, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetSingleBySpecificationAsync(specification, cancellationToken);
        }

        public async Task<int> CountAsync(ISpecification<City>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.CountAsync(specification, cancellationToken);
        }

        public async Task<bool> AnyAsync(ISpecification<City>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.AnyAsync(specification, cancellationToken);
        }

        public async Task<PagedResult<City>> GetPagedAsync(int page, int pageSize, ISpecification<City>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetPagedAsync(page, pageSize, specification, cancellationToken);
        }

        public async Task<IEnumerable<TResult>> GetProjectedAsync<TResult>(System.Linq.Expressions.Expression<Func<City, TResult>> projection, ISpecification<City>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetProjectedAsync(projection, specification, cancellationToken);
        }

        public async Task<PagedResult<TResult>> GetProjectedPagedAsync<TResult>(System.Linq.Expressions.Expression<Func<City, TResult>> projection, int page, int pageSize, ISpecification<City>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetProjectedPagedAsync(projection, page, pageSize, specification, cancellationToken);
        }

        // 实现IWriteRepository接口的新方法
        public async Task<City> AddAsync(City entity, CancellationToken cancellationToken = default)
        {
            return await _writeRepository.AddAsync(entity, cancellationToken);
        }

        public async Task<IEnumerable<City>> AddRangeAsync(IEnumerable<City> entities, CancellationToken cancellationToken = default)
        {
            return await _writeRepository.AddRangeAsync(entities, cancellationToken);
        }

        public async Task UpdateAsync(City entity, CancellationToken cancellationToken = default)
        {
            await _writeRepository.UpdateAsync(entity, cancellationToken);
        }

        public async Task UpdateRangeAsync(IEnumerable<City> entities, CancellationToken cancellationToken = default)
        {
            await _writeRepository.UpdateRangeAsync(entities, cancellationToken);
        }

        public async Task DeleteAsync(City entity, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteAsync(entity, cancellationToken);
        }

        public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteAsync(id, cancellationToken);
        }

        public async Task DeleteRangeAsync(IEnumerable<City> entities, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteRangeAsync(entities, cancellationToken);
        }

        public async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            return await _writeRepository.SaveChangesAsync(cancellationToken);
        }
    }
}